/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-08-24     yangjie      the first version
 */

/*
 * 程序清单：信号量例程
 *
 * 该例程创建了一个动态信号量，初始化两个线程，线程1在count每计数10次时，
 * 发送一个信号量，线程2在接收信号量后，对number进行加1操作
 */
#include <aos/aos.h>
#include "aos/cli.h"
#include <debug/dbg.h>

#define THREAD_PRIORITY         25
#define THREAD_TIMESLICE        5
#define THREAD_STACK_SIZE       2048

/* 指向信号量的指针 */
static aos_sem_t dynamic_sem = NULL;

/* 线程控制块 */
static aos_task_t tid1 = NULL;
static aos_task_t tid2 = NULL;
static void rt_thread1_entry(void *parameter)
{
    static unsigned char count = 0;

    while (1)
    {
        if (count <= 100)
        {
            count++;
        }
        else
            return;

        /* count每计数10次，就释放一次信号量 */
        if (0 == (count % 10))
        {
            aos_debug_printf("thread1 release a dynamic semaphore.\n");
            aos_sem_signal(&dynamic_sem);
        }
    }
}

static void rt_thread2_entry(void *parameter)
{
    static int result;
    static unsigned char number = 0;
    while (1)
    {
        /* 永久方式等待信号量，获取到信号量，则执行number自加的操作 */
        result = aos_sem_wait(&dynamic_sem, AOS_WAIT_FOREVER);
        if (result != 0)
        {
            aos_debug_printf("thread2 take a dynamic semaphore, failed.\n");
            aos_sem_free(&dynamic_sem);
            return;
        }
        else
        {
            number++;
            aos_debug_printf("thread2 take a dynamic semaphore. number = %d\n", number);
        }
    }
}

/* 信号量示例的初始化 */
int yoc_semaphore_sample(int argc, char **argv)
{
    int result;
    /* 创建一个动态信号量，初始值是0 */
    result = aos_sem_create(&dynamic_sem, 0, 0);
    if (result != 0)
    {
        aos_debug_printf("create dynamic semaphore failed.\n");
        return -1;
    }
    else
    {
        aos_debug_printf("create done. dynamic semaphore value = 0.\n");
    }
    aos_task_create(&tid1,
                    "thread1",
                    rt_thread1_entry, NULL,
                    NULL,
                    THREAD_STACK_SIZE,
                    THREAD_PRIORITY,
                    AOS_TASK_AUTORUN);

    aos_task_create(&tid2,
                    "thread2",
                    rt_thread2_entry, NULL,
                    NULL,
                    THREAD_STACK_SIZE,
                    THREAD_PRIORITY - 1,
                    AOS_TASK_AUTORUN);

    return 0;
}

ALIOS_CLI_CMD_REGISTER(yoc_semaphore_sample, yoc_semaphore_sample,yoc semaphore sample);

